package ca.magex.gps.loader;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.xml.sax.Attributes;
import org.xml.sax.SAXException;

import ca.magex.gps.entity.impl.GarminTrack;
import ca.magex.gps.entity.impl.LapImpl;
import ca.magex.gps.entity.impl.LatLongPointImpl;
import ca.magex.gps.entity.impl.TrackpointImpl;

public class LoadMyTracksFileHandler extends FileHandler {

	private List<GarminTrack> tracks;

	private GarminTrack cTrack;
	
	private LapImpl cLap;
	
	private TrackpointImpl cTrackpoint;
	
	private String content;
	
	LoadMyTracksFileHandler() {
		
	}
	
	@Override
	public void startDocument() {
		tracks = new ArrayList<GarminTrack>();
	}

	@Override
	public void endDocument() throws SAXException {

	}

	@Override
	public void characters(char[] ch, int start, int length) throws SAXException {
		for (int i = start; i < start + length; i++) {
			content += ch[i];
		}
	}

	@Override
	public void startElement(String uri, String localName, String name, Attributes attributes) throws SAXException {
		if (name.equals("trk")) {
			startTrack();
		} else if (name.equals("trkseg")) {
			startLap();
		} else if (name.equals("trkpt")) {
			startTrackpoint(attributes);
		}
		content = "";
	}

	@Override
	public void endElement(String uri, String localName, String name) throws SAXException {
		if (name.equals("ele")) {
			endElevation();
		} else if (name.equals("time")) {
			endTrackpointTime();
		}
	}
	
	private void startTrack() {
		cTrack = new GarminTrack();
		tracks.add(cTrack);
	}
	
	private void startLap() {
		cLap = new LapImpl();
		cTrack.addLap(cLap);
	}
	
	private void startTrackpoint(Attributes attributes) {
		cTrackpoint = new TrackpointImpl();
		cTrackpoint.setPoint(new LatLongPointImpl(Double.parseDouble(attributes.getValue("lat")), Double.parseDouble(attributes.getValue("lon"))));
		cLap.addTrackpoint(cTrackpoint);
	}
	
	private void endElevation() {
		if (cTrackpoint != null)
			cTrackpoint.setAltitude(Double.parseDouble(content));
	}
	
	private void endTrackpointTime() {
		try {
			String dateStr = content.substring(0, 10) + " " + content.substring(11, 19);
			Date t = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(dateStr);
			cTrackpoint.setTime(t);
		} catch (ParseException e) {
			e.printStackTrace();
			throw new RuntimeException("Invalid date time, cannot parse " + content);
		}
	}

	public List<GarminTrack> getData() {
		return tracks;
	}
	
}
